external usleep : int -> unit = "ml_usleep"

(* FFmpeg libs *)
external c_video_init : string -> ('a, 'b, Bigarray.c_layout) Bigarray.Array1.t -> int = "video_init"

external next : int -> int = "video_next"
external width : int -> int = "width"
external height : int -> int = "height"
external pixel : int -> int -> int -> int = "pixel"

(* Interface *)
external c_init_context :
  ('a, 'b, Bigarray.c_layout) Bigarray.Array1.t -> int -> int = "init_context"

external c_set_screen_size :
  ('a, 'b, Bigarray.c_layout) Bigarray.Array1.t -> unit = "set_screen_size"

external c_set_video_zone :
  ('a, 'b, Bigarray.c_layout) Bigarray.Array1.t -> unit = "set_video_zone"

external c_draw_scene :
  ('a, 'b, Bigarray.c_layout) Bigarray.Array1.t -> (* infos *)
  ('c, 'd, Bigarray.c_layout) Bigarray.Array1.t -> (* chars *)
  ('e, 'f, Bigarray.c_layout) Bigarray.Array1.t -> (* colors *)
  int -> int -> int = "draw_scene"

external c_context_refresh :
  ('a, 'b, Bigarray.c_layout) Bigarray.Array1.t -> unit = "context_refresh"

external c_debug_pause : unit -> unit = "debug_pause"
external c_debug_display_ba :
  ('a, 'b, Bigarray.c_layout) Bigarray.Array1.t -> unit = "debug_display_ba"

let ba_size = 32;; (* auto upscale ? *)
let iba_screen_line = 1;;
let iba_screen_col = 2;;
let iba_context = 6;;
let iba_colorchar = 7;;
let iba_vid_nbchar_width = 8;;
let iba_vid_nbchar_height = 9;;
let iba_video_line = 10;; (* zone_video *)
let iba_video_col = 11;; (* zone_video *)
let iba_update_wvideo = 12;;
let iba_frame_rate_num = 13;;
let iba_frame_rate_den = 14;;

let int_of_bool = function
    true	-> 1
  | _		-> 0

(* grepme if color ; color : dyn *)
let ba = Bigarray.Array1.create Bigarray.int Bigarray.c_layout ba_size

let length vid = (width vid, height vid)

let video_frame vid i j =
  let pix = pixel vid i j in
  Color.init (pix / (16 * 16 * 16 * 16)) (pix / (16 * 16) mod 256) (pix mod 256)


let true_ratio ba img_w img_h =
  c_set_screen_size ba; (* grepme bad infos ? *)
  let room_h = ba.{iba_video_line} in
  let room_w = ba.{iba_video_col} in
  let w = float img_w in
  let h = float img_h in
  let tmp = max (w /. (float room_w)) (h /. ((float room_h) *. 2.)) in
  max tmp 1.

(* Main Loop *)
let treat fichier conv_string colored =
  ignore(c_init_context ba (int_of_bool false));
  let video = c_video_init fichier ba in
  let (ww, hh) = length video in (* in pixels *)

  let conv_params =
    Conv.create_conv_params
      (Bigarray.Array1.create
	 Bigarray.char Bigarray.c_layout ((ww + 1) * (hh / 2)))

      (Bigarray.Array1.create
       Bigarray.int Bigarray.c_layout (((ww + 1) * (hh / 2)) * 3))

      (video_frame video)
      ww
      (hh / 2)
      1.
      conv_string
      0
  in
  (* let th_descr = Thread.create Conv.looper conv_params in *)

  begin
    while (true) do
      Conv.set_actu conv_params (next video);

      usleep 1;

      if (ba.{iba_update_wvideo} = 1) then
      	begin
      	  Conv.set_ratio conv_params (true_ratio ba ww hh);

      	  Conv.set_w conv_params
      	    (truncate (float(ww) /. (Conv.get_ratio conv_params)));

      	  Conv.set_h conv_params
      	    (truncate (float(hh) /. (2. *. (Conv.get_ratio conv_params))));

      	  ba.{iba_vid_nbchar_height} <- Conv.get_h conv_params;
      	  ba.{iba_vid_nbchar_width} <- Conv.get_w conv_params;

      	  c_set_video_zone ba;
      	  c_context_refresh ba;

      	  ba.{iba_update_wvideo} <- 0;
      	end;

      (* Thread.yield (); *)

      Conv.vta conv_params;

      ignore (c_draw_scene
      		ba
		(Conv.get_tab conv_params)
		(Conv.get_ba_color conv_params)
		0
		video); (* grepme need to fix color-mode setting *)

      done
  end
